<script setup lang="ts">
import { ref, watch, onMounted, nextTick } from 'vue';
import { NModal, NCard, NButton, NSpace, NDataTable, NTabs, NTabPane, NSpin, useMessage } from 'naive-ui';
import type { DataTableColumns } from 'naive-ui';
import { executeSqlTask, fetchExecutionPlan, type DevTask, type ExecutionPlan } from '@/service/api/dataplatform/dev';
import * as monaco from 'monaco-editor';

interface Props {
  visible: boolean;
  task: DevTask | null;
}

interface Emits {
  (e: 'update:visible', visible: boolean): void;
}

const props = defineProps<Props>();
const emit = defineEmits<Emits>();

const message = useMessage();
const loading = ref(false);
const executing = ref(false);
const editorContainer = ref<HTMLElement>();
let editor: monaco.editor.IStandaloneCodeEditor | null = null;

const activeTab = ref('result');
const executionResult = ref<any>(null);
const executionPlan = ref<ExecutionPlan | null>(null);

// 结果表格列
const resultColumns = ref<DataTableColumns<any>>([]);
const resultData = ref<any[]>([]);

// 初始化编辑器
function initEditor() {
  if (!editorContainer.value) return;

  editor = monaco.editor.create(editorContainer.value, {
    value: props.task?.content || '',
    language: 'sql',
    theme: 'vs-dark',
    automaticLayout: true,
    minimap: { enabled: false },
    fontSize: 14,
    lineNumbers: 'on',
    scrollBeyondLastLine: false,
    wordWrap: 'on'
  });
}

// 执行SQL
async function handleExecute() {
  if (!editor || !props.task) return;

  const sql = editor.getValue();
  if (!sql.trim()) {
    message.warning('请输入SQL语句');
    return;
  }

  executing.value = true;
  activeTab.value = 'result';

  try {
    const res = await executeSqlTask(props.task.id!);
    executionResult.value = res.data;

    if (res.data.columns && res.data.rows) {
      // 构建表格列
      resultColumns.value = res.data.columns.map((col: any) => ({
        title: col.name,
        key: col.name,
        ellipsis: { tooltip: true }
      }));
      resultData.value = res.data.rows;
      message.success(`查询成功，返回 ${res.data.rowCount} 行`);
    } else if (res.data.affectedRows !== undefined) {
      message.success(`执行成功，影响 ${res.data.affectedRows} 行`);
    }
  } catch (error: any) {
    message.error(error.message || '执行失败');
    executionResult.value = { status: 'FAILED', error: error.message };
  } finally {
    executing.value = false;
  }
}

// 获取执行计划
async function handleGetPlan() {
  if (!props.task) return;

  loading.value = true;
  try {
    const res = await fetchExecutionPlan(props.task.id!);
    executionPlan.value = res.data;
    activeTab.value = 'plan';
    message.success('获取执行计划成功');
  } catch (error: any) {
    message.error(error.message || '获取执行计划失败');
  } finally {
    loading.value = false;
  }
}

// 格式化SQL
function handleFormat() {
  if (!editor) return;
  editor.getAction('editor.action.formatDocument')?.run();
}

// 关闭弹窗
function handleClose() {
  emit('update:visible', false);
}

// 监听visible变化
watch(
  () => props.visible,
  async val => {
    if (val) {
      await nextTick();
      if (!editor) {
        initEditor();
      } else if (props.task) {
        editor.setValue(props.task.content || '');
      }
      executionResult.value = null;
      executionPlan.value = null;
      resultColumns.value = [];
      resultData.value = [];
    }
  }
);

onMounted(() => {
  // Monaco Editor will be initialized when modal opens
});
</script>

<template>
  <NModal
    :show="visible"
    preset="card"
    :title="`SQL编辑器 - ${task?.name || ''}`"
    style="width: 90%; max-width: 1400px; height: 80vh"
    @update:show="handleClose"
  >
    <div class="h-full flex-col-stretch gap-16px">
      <!-- 工具栏 -->
      <div class="flex-y-center justify-between">
        <NSpace>
          <NButton type="primary" :loading="executing" @click="handleExecute">
            <icon-ic-round-play-arrow class="mr-4px text-20px" />
            执行
          </NButton>
          <NButton @click="handleGetPlan">
            <icon-ic-round-analytics class="mr-4px text-20px" />
            执行计划
          </NButton>
          <NButton @click="handleFormat">
            <icon-ic-round-format-align-left class="mr-4px text-20px" />
            格式化
          </NButton>
        </NSpace>
      </div>

      <!-- 编辑器 -->
      <div ref="editorContainer" class="flex-1 border rounded" style="min-height: 300px"></div>

      <!-- 结果区域 -->
      <div class="flex-1 overflow-hidden">
        <NTabs v-model:value="activeTab" type="line">
          <NTabPane name="result" tab="执行结果">
            <NSpin :show="executing">
              <div v-if="executionResult" class="h-400px overflow-auto">
                <div v-if="executionResult.status === 'SUCCESS'">
                  <NDataTable
                    v-if="resultColumns.length > 0"
                    :columns="resultColumns"
                    :data="resultData"
                    :scroll-x="1000"
                    size="small"
                    :max-height="350"
                  />
                  <div v-else class="text-center py-20px">
                    <div class="text-success">执行成功</div>
                    <div v-if="executionResult.affectedRows !== undefined" class="mt-8px">
                      影响行数: {{ executionResult.affectedRows }}
                    </div>
                  </div>
                </div>
                <div v-else-if="executionResult.status === 'FAILED'" class="text-center py-20px">
                  <div class="text-error">执行失败</div>
                  <div class="mt-8px text-gray">{{ executionResult.error }}</div>
                </div>
              </div>
              <div v-else class="text-center py-40px text-gray">暂无执行结果</div>
            </NSpin>
          </NTabPane>

          <NTabPane name="plan" tab="执行计划">
            <div v-if="executionPlan" class="h-400px overflow-auto">
              <pre class="bg-gray-50 p-12px rounded text-12px">{{ executionPlan.planText }}</pre>
              <div v-if="executionPlan.steps && executionPlan.steps.length > 0" class="mt-16px">
                <div class="font-bold mb-8px">执行步骤:</div>
                <div v-for="step in executionPlan.steps" :key="step.stepId" class="mb-8px p-8px bg-gray-50 rounded">
                  <div>步骤 {{ step.stepId }}: {{ step.operationType }}</div>
                  <div v-if="step.tableName" class="text-12px text-gray">表: {{ step.tableName }}</div>
                  <div v-if="step.indexUsed" class="text-12px text-gray">索引: {{ step.indexUsed }}</div>
                </div>
              </div>
            </div>
            <div v-else class="text-center py-40px text-gray">暂无执行计划</div>
          </NTabPane>
        </NTabs>
      </div>
    </div>
  </NModal>
</template>

<style scoped>
.border {
  border: 1px solid #e0e0e0;
}
</style>
